<?php

namespace App\Services\Aliyun\upload;

use App\Models\ImFilesStorage;
use App\Services\Aliyun\BaseService;
use App\Services\Configs\DefaultService;
use Illuminate\Http\Request;
use OSS\OssClient;
use OSS\Core\OssException;

class AliyunUploadServices extends BaseService
{
    private $accessKeyId;
    private $accessKeySecret;
    private $endpoint;
    private $bucket;

    public function __construct()
    {
        if (is_file(__DIR__ . '/../autoload.php')) {
            require_once __DIR__ . '/../autoload.php';
        }
        if (is_file(__DIR__ . '/../vendor/autoload.php')) {
            require_once __DIR__ . '/../vendor/autoload.php';
        }
        $config = $this->getConfig(DefaultService::ALI_OSS);
        $this->accessKeyId = $config['accessKeyId'];
        $this->accessKeySecret = $config['accessKeySecret'];
        $this->endpoint = $config['endpoint'];
//        $this->publicBucket = 'tangfens';  //私有桶名称
//        $this->privateBucket = 'privateceshi';  //公共桶名称
        $this->publicBucket = 'uploadpublicbuckets';  //公共桶名称
        $this->privateBucket = 'uploadprivatebuckets';  //私有桶名称
    }

    /**上传图片或者视频**添加智能图片/视频审核**设置权限
     * @param Request $request
     * file  上传文件绝对路劲 $request->file('file');
     * folder 自定义上传到对应的桶的文件夹（自动创建）
     * $type 文件的权限类型 //私有1, 公共读2,公共读写3
     * @return \Illuminate\Http\JsonResponse
     */
    public function uploadImg($file, $folder, $type)
    {
        if (empty($file) || empty($folder) || empty($type)) {
            return false;
        }
        // 要上传文件的本地路径
        $filePath = $file->getRealPath();
        // 上传到七牛后保存的文件名
        $fileName = $folder.'/'.date('Ymd') . '/' . date('YmdHis') . uniqid() . '.'.$file->getClientOriginalExtension();

        if($type==1){//私有
            $bucket  = $this->privateBucket;
        }else{
            $bucket  = $this->publicBucket;
        }
        try {
            $ossClient = new OssClient($this->accessKeyId, $this->accessKeySecret, $this->endpoint);
            $res = $ossClient->uploadFile($bucket, $fileName, $filePath, []);
            return $res;
        } catch (OssException $e) {
            return 1;//上传失败
        }
    }

    /**上传图片或者视频**添加智能图片/视频审核**设置权限
     * @param Request $request
     * file  上传文件绝对路劲 $request->file('file');
     * folder 自定义上传到对应的桶的文件夹（自动创建）
     * $type 文件的权限类型 //私有1, 公共读2,公共读写3
     * @return \Illuminate\Http\JsonResponse
     */
    public function uploadAliImg($url, $type, $gid)
    {
        if (empty($url) || empty($type)) {
            return false;
        }

        $fileName = 'tangfen' . '/' . $gid.'.jpg';//文件名称
        $filePath = $url;
        if($type==1){//私有
            $bucket  = $this->privateBucket;
        }else{
            $bucket  = $this->publicBucket;
        }
        try {
            $ossClient = new OssClient($this->accessKeyId, $this->accessKeySecret, $this->endpoint);
            $res = $ossClient->uploadFile($bucket, $fileName, $filePath, []);
            return $res;
        } catch (OssException $e) {
            return 1;//上传失败
        }
    }



    /**
     *获取文件临时访问权限
     * @param $url  填写不包含Bucket名称在内的Object完整路径。
     * @param int $expires  临时凭证过期时间
     *author:tangfen
     *date:$ct
     */
    public function downloadUrl($url,$timeout=3600000){
        if (empty($url)) {
            return false;
        }
        try {
            $ossClient = new OssClient($this->accessKeyId, $this->accessKeySecret, $this->endpoint, false);
            // 生成GetObject的签名URL。 填写Bucket名称。 填写不包含Bucket名称在内的Object完整路径。   设置签名URL的有效时长为3600秒。
            $signedUrl = $ossClient->signUrl($this->privateBucket, $url, $timeout);
            return $signedUrl;
        } catch (OssException $e) {
            return 1;// printf($e->getMessage() . "\n");
        }
    }

    /**
     *文本上传
     * @param $textName 文件名称(不需要后缀)
     * @param $content  填写待上传的字符串
     *author:tangfen
     *date:$ct
     */
    public function uploadIext($textName, $content)
    {
        if (empty($textName) || empty($content)) {
            return false;
        }
        $object = "text/" . date('Ymd') . '/' . $textName . ".txt";     //"exampledir/exampleobject.txt";
        try {
            $ossClient = new OssClient($this->accessKeyId, $this->accessKeySecret, $this->endpoint);
            $res = $ossClient->putObject($this->bucket, $object, $content);
            return $res;
        } catch (OssException $e) {
            return 1;//错误   printf($e->getMessage() . "\n");
        }
    }

    /**
     *删除文件
     * @param $file_id
     *author:tangfen
     *date:$ct
     */
    public function delFile($file){
        $path_file=trim(parse_url($file)['path'],'/');//去掉域名,
        //数据入库
        $ImFilesStorage = new ImFilesStorage();
        $power =  $ImFilesStorage->where('link_url', $file)->value('power'); //私有1, 公共读2,公共读写3
        if($power!=1){
            $bucket = $this->publicBucket; //公开桶
        }else{
            $bucket = $this->privateBucket; //私有桶
        }
        try {
            $ossClient = new OssClient($this->accessKeyId, $this->accessKeySecret, $this->endpoint);
            $ossClient->deleteObject($bucket, $path_file);
            //软删数据库状态
            $file = ImFilesStorage::where('link_url', $file)->first();
            $file->status = 3;  //3已删除
            $file->save();
            return 2;//成功
        } catch (\Exception $e) {
            return 1;//请求失败  echo($e);
        }
    }

    /**下载图片或者视频
     * @param Request $request
     * url 保存的阿里云oss图片地址
     * @return \Illuminate\Http\JsonResponse
     */
    public function downloadImg($url)
    {
        if (empty($url)) {
            return false;
        }
        $url = explode('/', $url);
        $buckets = explode('.', $url[2]);
        $bucket = $buckets[0];
        $object = $url[3] . '/' . $url[4] . '/' . $url['5'];
        $localfile = "upload/" . $url[4] . '/' . $url['5'];
        $options = array(//设置下载保存路劲
            OssClient::OSS_FILE_DOWNLOAD => $localfile
        );
        try {
            $ossClient = new OssClient($this->accessKeyId, $this->accessKeySecret, $this->endpoint);
            $ossClient->getObject($bucket, $object, $options);
            return $localfile;
        } catch (OssException $e) {
            return 1;//错误
        }
    }

    /**获取图片信息
     * @param Request $request
     * url 保存的阿里云oss图片地址
     * @return \Illuminate\Http\JsonResponse
     */
    public function getImg($etag)
    {
        if (empty($etag)) {
            return false;
        }
        try {
            $ossClient = new OssClient($this->accessKeyId, $this->accessKeySecret, $this->endpoint);
            $listObjectInfo = $ossClient->listObjects($this->bucket);
            $objectList = $listObjectInfo->getObjectList();
            if (!empty($objectList)) {
                foreach ($objectList as $k => $objectInfo) {
                    $etagKey = trim($objectInfo->getETag(), '"');
                    if ($etagKey == $etag) {
                        $data = [
                            'key' => $objectInfo->getKey(),
                            'LastModified' => $objectInfo->getLastModified(),
                            'type' => $objectInfo->getType(),
                            'size' => $objectInfo->getSize(),
                            'SizeStr' => $objectInfo->getSizeStr(),
                            'StorageClass' => $objectInfo->getStorageClass(),
                            'etag' => $etag,
                        ];
                        return $data;
                    }
                }
            }
        } catch (OssException $e) {
            return 1;//错误  print $e->getMessage();
        }
    }

    /**设置文件的元信息
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     * @author tangfen
     */
    public function setUploadInformation($fileUrl, $expiresTime, $title, $content)
    {
        if (empty($fileUrl) || empty($title) || empty($expiresTime) || empty($content)) {
            return false;
        }
        // yourObjectName表示想要设置文件元信息的Object所在存储空间的完整名称，即包含文件后缀在内的完整路径，如填写为example/test.jpg。
        $objectName = explode('com/', $fileUrl);
        $object = $objectName[1];          //"bbb/20211130/2021113011434861a59df4627d1.mp4";
        $options = array(
            OssClient::OSS_HEADERS => array(
                'Expires' => $expiresTime,
                'Content-Disposition' => 'attachment; filename=' . $title,
                'x-oss-meta-self-define-title' => $title,
            ));
        try {
            $ossClient = new OssClient($this->accessKeyId, $this->accessKeySecret, $this->endpoint);
            $result = $ossClient->putObject($this->bucket, $object, $content, $options);
            return $result;
        } catch (OssException $e) {
            return 1;   //错误  printf($e->getMessage() . "\n");
        }
    }

    /**修改文件元信息
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     * @author tangfen
     */
    public function updateUploadInformation($fileUrl, $expiresTime, $title, $toObject)
    {
        if (empty($fileUrl) || empty($title) || empty($expiresTime) || empty($toObject)) {
            return false;
        }
        $objectName = explode('com/', $fileUrl);
        $object = $objectName[1];
        $fromBucket = $this->bucket;//原文件桶
        $fromObject = $object;//原文件名称
        $toBucket = $this->bucket;//修改的桶名称
        $copyOptions = array(
            OssClient::OSS_HEADERS => array(
                'Expires' => $expiresTime,
                'Content-Disposition' => 'attachment; filename=' . $title,
                'x-oss-meta-location' => 'location',
                // 指定设置目标Object元信息的方式，此处以指定为'REPLACE'为例，表示忽略源Object的元数据，直接采用请求中指定的元数据。若设置为COPY，表示复制源Object的元数据到目标Object。
                'x-oss-metadata-directive' => 'REPLACE',//REPLACE   COPY
            ),
        );
        try {
            $ossClient = new OssClient($this->accessKeyId, $this->accessKeySecret, $this->endpoint);
            $result = $ossClient->copyObject($fromBucket, $fromObject, $toBucket, $toObject, $copyOptions);
            return $result;
        } catch (OssException $e) {
            return 1; // printf($e->getMessage() . "\n");
        }
    }

    /**获取文件元信息
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     * @author tangfen
     */
    public function getUploadInformation($fileUrl)
    {
        if (empty($fileUrl)) {
            return false;
        }
        $objectName = explode('com/', $fileUrl);
        $object = $objectName[1];//yourObjectName
        $ossClient = new OssClient($this->accessKeyId, $this->accessKeySecret, $this->endpoint);
        try {
            // 获取文件的全部元信息。
            $objectMeta = $ossClient->getObjectMeta($this->bucket, $object);
            return $objectMeta;
//            // 获取文件的部分元信息。
//            $objectMeta = $ossClient->getSimplifiedObjectMeta($this->bucket, $object);
        } catch (OssException $e) {
            return 1;    // printf($e->getMessage() . "\n");
        }
    }

}
